using System;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

using ZombieHigh2.Controller;
using ZombieHigh2.Interfaces;
using ZombieHigh2.Audio;
using QuadAnimation.Animation;

namespace ZombieHigh2.Actor
{

    public enum PlayerState
    {
        PSTATE_IDLE,
        PSTATE_STUNNED,
        PSTATE_WALKING,
        PSTATE_ATTACKING,
        PSTATE_DEAD
    }

    public enum PlayerDirection
    {
        PDIR_LEFT,
        PDIR_RIGHT
    }

    public class BaseActor : InfoEvents
    {
        public PlayerState CurrentPlayerState;
        public PlayerState LastPlayerState;
        public float IdleTime;
        public float StunTime;

        protected BaseController InputController;
        protected Vector3 Position;
        protected Vector3 Velocity;

        //protected AnimatedQuad Quad;
        protected AnimatedObject AnimatedObject;

        protected bool Attack;

        //protected float AnimationTime;
        //protected float AnimationTimePerFrame = 0.25f;
        //protected int AnimationStartFrame;
        //protected int AnimationEndFrame;
        //protected int AnimationCurrentFrame;
        //protected String AnimationCycleName;
        //protected bool AnimationLoops = false;

        protected PlayerDirection Direction;

        protected int Health;

        protected ActionEvents Actions;

        protected BoundingBox BBox;

        protected bool Dead;
        protected AudioSystem Audio;

        public float Depth;

        public bool IsDead
        {
            get { return Dead; }
            set { Dead = value; }
        }

        public int HealthAmount
        {
            get { return Health; }
        }

        public bool Attacking
        {
            get { return Attack; }
            set { Attack = value; }
        }

        public Vector3 Pos
        {
            get { return Position; }
            set { Position = value; }
        }

        public Vector3 Vel
        {
            get { return Velocity; }
            set { Velocity = value; }
        }

        public BoundingBox BoundingBox
        {
            get { return BBox; }
        }

        public float Width
        {
            get { return BBox.Max.X - BBox.Min.X; }
        }

        public BoundingBox CollisionBox
        {
            get
            {
                Matrix transformation = Matrix.CreateTranslation(Position);

                return new BoundingBox(Vector3.Transform(BBox.Min, transformation),
                    Vector3.Transform(BBox.Max, transformation));
            }
        }

        public BaseActor(ActionEvents actionEvents, AudioSystem audio, AnimatedObject animatedObject)
        {
            Position = Vector3.Zero;
            Velocity = Vector3.Zero;
            Direction = PlayerDirection.PDIR_LEFT;
            CurrentPlayerState = PlayerState.PSTATE_IDLE;
            LastPlayerState = PlayerState.PSTATE_IDLE;
            Health = 10;
            this.AnimatedObject = animatedObject;
            AnimatedObject.OnAnimationEnd += new AnimatedObject.AnimationEnd(OnAnimationEnd);

            Actions = actionEvents;
            Depth = 32f;

            BBox = new BoundingBox(new Vector3(-48, -64, -Depth/2), new Vector3(48, 64, Depth/2));
            Dead = false;
            Audio = audio;

            IdleTime = 0f;
            StunTime = 0f;
        }

        public virtual void Load()
        {
        }

        public virtual void Update(GameTime gameTime)
        {
            float elapsedTime = (float)gameTime.ElapsedGameTime.TotalSeconds;
            CheckCurrentState();

            //Update the animated object
            AnimatedObject.Update(gameTime);

            if (InputController != null)
            {
                InputController.Update(elapsedTime);
            }

            if (Direction == PlayerDirection.PDIR_LEFT)
            {
                AnimatedObject.Flip = true;
            }
            else
            {
                AnimatedObject.Flip = false;
            }
        }

        void CheckCurrentState()
        {
            if (CurrentPlayerState != LastPlayerState)
            {
                if (CurrentPlayerState == PlayerState.PSTATE_IDLE)
                {
                    AnimatedObject.PlaySequence("idle");
                }
                else if (CurrentPlayerState == PlayerState.PSTATE_WALKING)
                {
                    AnimatedObject.PlaySequence("walk");
                }
                else if (CurrentPlayerState == PlayerState.PSTATE_ATTACKING)
                {
                    AnimatedObject.PlaySequence("attack");
                }
                else if (CurrentPlayerState == PlayerState.PSTATE_DEAD)
                {
                    AnimatedObject.PlaySequence("idle");
                }
                else if (CurrentPlayerState == PlayerState.PSTATE_STUNNED)
                {
                    AnimatedObject.PlaySequence("idle");
                }
            }
        }

        protected void SetCurrentState(PlayerState currentState)
        {
            LastPlayerState = CurrentPlayerState;
            CurrentPlayerState = currentState;
        }

        public virtual void Draw(GraphicsDevice device)
        {
            AnimatedObject.Draw(device);
        }

        protected virtual void OnAnimationEnd()
        {
        }


        public virtual void OnHit(int amount)
        {
        }

        public virtual void Info_Damage(BaseActor who, int amount)
        {
        }

        public virtual void Info_PlayerLocation(Vector3 player)
        {
        }

        public virtual void Info_IdleTimeUp()
        {
        }

        public virtual void Info_StunTimeUp()
        {
        }

        public virtual void Info_HealthLessThanZero()
        {
        }
    }
}
